-- Tests for too large/small p, and type mismatches for vec and reference_vec
SET allow_experimental_qbit_type = 1;


{% for i in range(0, 2) -%}
SET optimize_qbit_distance_function_reads = {{ i }};

-- BFloat16
DROP TABLE IF EXISTS qbit;
CREATE TABLE qbit (id UInt32, vec QBit(BFloat16, 3)) ENGINE = Memory;

INSERT INTO qbit VALUES (1, [0,1,2]);
INSERT INTO qbit VALUES (2, [1,2,3]);
INSERT INTO qbit VALUES (3, [2,3,4]);

-- Use rounding to avoid minor precision differences when using non-vectorized implementations of distance function
WITH [toBFloat16(0), 1, 2] AS reference_vec SELECT id, vec, round(L2DistanceTransposed(vec, reference_vec, 0), 5) AS dist FROM qbit ORDER BY id; -- { serverError BAD_ARGUMENTS }
WITH [toBFloat16(0), 1, 2] AS reference_vec SELECT id, vec, round(L2DistanceTransposed(vec, reference_vec, 17), 5) AS dist FROM qbit ORDER BY id; -- { serverError BAD_ARGUMENTS }
WITH [toFloat32(0), 1, 2] AS reference_vec SELECT id, vec, round(L2DistanceTransposed(vec, reference_vec, 1), 5) AS dist FROM qbit ORDER BY id;
WITH [toFloat64(0), 1, 2] AS reference_vec SELECT id, vec, round(L2DistanceTransposed(vec, reference_vec, 1), 5) AS dist FROM qbit ORDER BY id;
DROP TABLE qbit;


-- Float32
CREATE TABLE qbit (id UInt32, vec QBit(Float32, 3)) ENGINE = Memory;

INSERT INTO qbit VALUES (1, [0,1,2]);
INSERT INTO qbit VALUES (2, [1,2,3]);
INSERT INTO qbit VALUES (3, [2,3,4]);

WITH [toFloat32(0), 1, 2] AS reference_vec SELECT id, vec, round(L2DistanceTransposed(vec, reference_vec, 0), 5) AS dist FROM qbit ORDER BY id; -- { serverError BAD_ARGUMENTS }
WITH [toFloat32(0), 1, 2] AS reference_vec SELECT id, vec, round(L2DistanceTransposed(vec, reference_vec, 33), 5) AS dist FROM qbit ORDER BY id; -- { serverError BAD_ARGUMENTS }
WITH [toBFloat16(0), 1, 2] AS reference_vec SELECT id, vec, round(L2DistanceTransposed(vec, reference_vec, 1), 5) AS dist FROM qbit ORDER BY id;
WITH [toFloat64(0), 1, 2] AS reference_vec SELECT id, vec, round(L2DistanceTransposed(vec, reference_vec, 1), 5) AS dist FROM qbit ORDER BY id;
DROP TABLE qbit;


-- Float64
CREATE TABLE qbit (id UInt32, vec QBit(Float64, 3)) ENGINE = Memory;

INSERT INTO qbit VALUES (1, [0,1,2]);
INSERT INTO qbit VALUES (2, [1,2,3]);
INSERT INTO qbit VALUES (3, [2,3,4]);

WITH [toFloat64(0), 1, 2] AS reference_vec SELECT id, vec, round(L2DistanceTransposed(vec, reference_vec, 0), 5) AS dist FROM qbit ORDER BY id; -- { serverError BAD_ARGUMENTS }
WITH [toFloat64(0), 1, 2] AS reference_vec SELECT id, vec, round(L2DistanceTransposed(vec, reference_vec, 65), 5) AS dist FROM qbit ORDER BY id; -- { serverError BAD_ARGUMENTS }
WITH [toBFloat16(0), 1, 2] AS reference_vec SELECT id, vec, round(L2DistanceTransposed(vec, reference_vec, 1), 5) AS dist FROM qbit ORDER BY id;
WITH [toFloat32(0), 1, 2] AS reference_vec SELECT id, vec, round(L2DistanceTransposed(vec, reference_vec, 1), 5) AS dist FROM qbit ORDER BY id;
DROP TABLE qbit;


-- Test if vec contain more elements than reference_vec
CREATE TABLE qbit (id UInt32, vec QBit(BFloat16, 9)) ENGINE = Memory;

INSERT INTO qbit VALUES (1, [0,1,2,3,4,5,6,7,8]);

WITH [toBFloat16(0), 1, 2] AS reference_vec SELECT id, vec, L2DistanceTransposed(vec.1, reference_vec) AS dist FROM qbit ORDER BY id; -- { serverError TOO_FEW_ARGUMENTS_FOR_FUNCTION }
DROP TABLE qbit;


-- Test unexpected type
CREATE TABLE qbit (id UInt32, vec QBit(BFloat16, 5)) ENGINE = Memory;
INSERT INTO qbit VALUES (1, [0,1,2,3,4]);
INSERT INTO qbit VALUES (2, [1,2,3,4,5]);

WITH [toBFloat16(0), 1, 2] AS reference_vec SELECT id, L2DistanceTransposed(vec.1, vec.2, id, reference_vec) AS dist FROM qbit ORDER BY id; -- { serverError TOO_MANY_ARGUMENTS_FOR_FUNCTION }
DROP TABLE qbit;

-- Check if full column as third argument throws
SELECT L2DistanceTransposed([1, 2, 3]::QBit(Float32, 3), [1, 2, 3]::Array(Float32), materialize(1)); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }

-- Others
SELECT L2DistanceTransposed(); -- { serverError TOO_FEW_ARGUMENTS_FOR_FUNCTION }
SELECT L2DistanceTransposed(''); -- { serverError TOO_FEW_ARGUMENTS_FOR_FUNCTION }

-- Check if size mismatch throws
SELECT L2DistanceTransposed([1.0, 2.0, 3.0]::QBit(Float32, 3), [1, 2, 3, 4]::Array(Float32), 32); -- { serverError BAD_ARGUMENTS }

-- Check if non-const reference vector of wrong size throws
SELECT L2DistanceTransposed([1.0, 2.0, 3.0]::QBit(Float32, 3), range(rand() % 5 + 5)::Array(Float32), 32); -- { serverError BAD_ARGUMENTS }

-- Do not allow non-constant size
SELECT L2DistanceTransposed(''::FixedString(1), materialize(3), [1,2,3]::Array(Float32)); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }

-- https://github.com/ClickHouse/ClickHouse/issues/90401
SELECT L2DistanceTransposed([2, 0, 0, 0, 0, 0, 0, 0]::QBit(Float32, 8), [42.], 33) AS dist; -- { serverError BAD_ARGUMENTS }

{% endfor -%}
